package com.lanchetech.admin.service.impl;


import com.alibaba.excel.util.CollectionUtils;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.lanchetech.admin.service.AdminService;
import com.lanchetech.admin.service.WebService;
import com.lanchetech.bean.request.PageReq;
import com.lanchetech.bean.response.BasePageResp;
import com.lanchetech.bean.response.BaseResp;
import com.lanchetech.bean.response.ResultData;
import com.lanchetech.bean.util.PageHelpUtil;
import com.lanchetech.bean.vo.AdminHomeStatisticsVO;
import com.lanchetech.bean.vo.CustomPageDataVO;
import com.lanchetech.bean.vo.CustomPageEditVO;
import com.lanchetech.bean.vo.OnePostVO;
import com.lanchetech.common.enums.*;
import com.lanchetech.dao.*;
import com.lanchetech.entity.*;
import com.lanchetech.service.DaoService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.TimeUnit;

@Service
public class WebServiceImpl implements WebService {

    @Autowired
    WebConfigMapper webConfigMapper;

    @Autowired
    AdminService adminService;


    @Autowired
    UserMapper userMapper;


    @Autowired
    WithdrawMapper withdrawMapper;

    @Autowired
    RedisTemplate redisTemplate;

    @Autowired
    AfterSaleMapper afterSaleMapper;

    @Autowired
    OrdersMapper ordersMapper;

    @Autowired
    BannerMapper bannerMapper;

    @Autowired
    NavigationMapper navigationMapper;

    @Autowired
    SpuMapper spuMapper;

    @Autowired
    ArticleMapper articleMapper;

    @Autowired
    AreaMapper areaMapper;

    @Autowired
    AdvertisementMapper advertisementMapper;

    @Autowired
    DaoService daoService;

    @Autowired
    CustomPageDataMapper customPageDataMapper;

    @Autowired
    CustomPageMapper customPageMapper;

    @Autowired
    PosterMapper posterMapper;

    @Autowired
    HipoConfigMapper hipoConfigMapper;

    @Autowired
    OnePostMapper onePostMapper;

    @Override
    public ResultData<List<WebConfig>> getAllWebConfig() {
        List<WebConfig> list = webConfigMapper.findAll();
        return new ResultData<>(list);
    }

    @Override
    public BaseResp modifyWebConfig(WebConfig webConfig) {
        webConfigMapper.updateValueAndUpdatedAtByName(webConfig);

        redisTemplate.delete("HomeInfoResp");
        return new BaseResp();
    }

    @Override
    public ResultData<List<HipoConfig>> getHipoConfigList() {
        return new ResultData<>(hipoConfigMapper.findAll());
    }

    @Override
    public BaseResp modifyHipoConfig(HipoConfig req) {
        req.setUpdatedAt(new Date());
        hipoConfigMapper.updateValueAndUpdatedAtByName(req);
        // 重置HipoConfig缓存
        ValueOperations<String, Map<String, String>> operations = redisTemplate.opsForValue();
        List<HipoConfig> hipoConfigs = hipoConfigMapper.findAll();
        HashMap map = new HashMap<>();
        for (HipoConfig item : hipoConfigs) {
            map.put(item.getName(), item.getValue());
        }
        operations.set("HipoConfig", map);

        redisTemplate.delete("HomeInfoResp");
        return new BaseResp();
    }

    public Date getDateStart(Calendar calendar) {
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime();
    }

    public Date getDateEnd(Calendar calendar) {
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        calendar.set(Calendar.MILLISECOND, 999);
        return calendar.getTime();
    }

    @Override
    public ResultData<AdminHomeStatisticsVO> getHomeStatistics() {
        ValueOperations<String, AdminHomeStatisticsVO> operations = redisTemplate.opsForValue();
        AdminHomeStatisticsVO vo = new AdminHomeStatisticsVO();
        Date date = new Date();//取时间
        Calendar calendar = Calendar.getInstance();

        // 缓存10分钟的
        String minuteKey = "AdminHomeStatisticsMinute";
        AdminHomeStatisticsVO minuteResult = operations.get(minuteKey);
        if (minuteResult != null) {
            return new ResultData<>(minuteResult);
        } else {
            calendar.setTime(date);
            Date todayStart = getDateStart(calendar);
            vo.setTodayOrder(ordersMapper.countByTimeRange(todayStart, date));
            vo.setWaitDelivery(ordersMapper.countByStatusAndLogisticsStatus(OrdersStatusEnum.PAID.getStatus()));
            vo.setAfterSale(afterSaleMapper.countByStatus(AfterSaleStatusEnum.PROCESSING.getStatus()));
            vo.setReturnConfirm(afterSaleMapper.countByStatus(AfterSaleStatusEnum.CONFIRM.getStatus()));

            // 缓存1天的
            String dayKey = "AdminHomeStatisticsDay";
            AdminHomeStatisticsVO dayResult = operations.get(dayKey);
            if (dayResult != null) {
                BeanUtils.copyProperties(dayResult, vo, "todayOrder", "waitDelivery", "afterSale", "returnConfirm");
            } else {
                calendar.setTime(date);
                Date todayEnd = getDateEnd(calendar);
                calendar.add(Calendar.DATE, -1);
                Date yesterdayStart = getDateStart(calendar);
                Date yesterdayEnd = getDateEnd(calendar);
                calendar.setTime(date);
                calendar.add(Calendar.DATE, -8);
                Date weekBeforeStart = getDateStart(calendar);

                vo.setTotalUser(userMapper.countAll());
                vo.setWeekUser(userMapper.countByTimeRange(weekBeforeStart, yesterdayEnd));
                vo.setYesterdayUser(userMapper.countByTimeRange(yesterdayStart, yesterdayEnd));
                vo.setYesterdayOrder(ordersMapper.countByTimeRange(yesterdayStart, yesterdayEnd));
                operations.set(dayKey, vo, todayEnd.getTime() - date.getTime(), TimeUnit.MILLISECONDS);
            }

            operations.set(minuteKey, vo, 10, TimeUnit.MINUTES);
            return new ResultData<>(vo);
        }
    }

    @Override
    public BaseResp editBanner(Banner banner) {
        if (banner.getId() == null) {
            // 添加
            banner.setCreatedAt(new Date());
            banner.setUpdatedAt(new Date());
            bannerMapper.insert(banner);
        } else {
            // 编辑
            banner.setUpdatedAt(new Date());
            bannerMapper.updateByPrimaryKeySelective(banner);
        }
        redisTemplate.delete("HomeInfoResp");
        return new BaseResp();
    }

    @Override
    public ResultData<BasePageResp<Banner>> getBannerPage(PageReq req) {
        Page page = PageHelper.startPage(req.getPageNo(), req.getPageSize());
        List<Banner> list = bannerMapper.findAllPage(req);
        return PageHelpUtil.buildPage(list, page);
    }

    @Override
    public BaseResp editNavigation(Navigation navigation) {
        if (navigation.getId() == null) {
            navigation.setCreatedAt(new Date());
            navigation.setUpdatedAt(new Date());
            navigationMapper.insert(navigation);
        } else {
            navigation.setUpdatedAt(new Date());
            navigationMapper.updateByPrimaryKeySelective(navigation);
        }
        redisTemplate.delete("HomeInfoResp");
        return new BaseResp();
    }

    @Override
    public ResultData<BasePageResp<Navigation>> getNavigationPage(PageReq req) {
        Page page = PageHelper.startPage(req.getPageNo(), req.getPageSize());
        List<Navigation> list = navigationMapper.findAllPage(req);
        return PageHelpUtil.buildPage(list, page);
    }

    @Override
    public ResultData<Banner> getBannerDetail(Long id) {
        return new ResultData<>(bannerMapper.selectByPrimaryKey(id));
    }

    @Override
    public BaseResp deleteBanner(Long id) {
        bannerMapper.deleteByPrimaryKey(id);
        redisTemplate.delete("HomeInfoResp");
        return new BaseResp();
    }

    @Override
    public ResultData<Navigation> getNavigationDetail(Long id) {
        return new ResultData<>(navigationMapper.selectByPrimaryKey(id));
    }

    @Override
    public BaseResp deleteNavigation(Long id) {
        navigationMapper.deleteByPrimaryKey(id);
        redisTemplate.delete("HomeInfoResp");
        return new BaseResp();
    }


    @Override
    public ResultData<BasePageResp<Advertisement>> getAdvertisementPage(PageReq req) {
        Page page = PageHelper.startPage(req.getPageNo(), req.getPageSize());
        List<Advertisement> list = advertisementMapper.findAllPage(req);
        return PageHelpUtil.buildPage(list, page);
    }

    @Override
    public ResultData<Advertisement> getAdvertisementDetail(Long id) {
        return new ResultData<>(advertisementMapper.selectByPrimaryKey(id));
    }

    @Override
    public BaseResp deleteAdvertisement(Long id) {
        advertisementMapper.deleteByPrimaryKey(id);
        return new BaseResp();
    }

    @Override
    public BaseResp editAdvertisement(Advertisement advertisement) {
        if (advertisement.getId() == null) {
            advertisement.setCreatedAt(new Date());
            advertisement.setUpdatedAt(new Date());
            advertisementMapper.insert(advertisement);
        } else {
            advertisement.setUpdatedAt(new Date());
            advertisementMapper.updateByPrimaryKeySelective(advertisement);
        }
        return new BaseResp();
    }


    @Override
    public BaseResp editCustomPage(CustomPageEditVO req) {
        CustomPage customPage = req.getCustomPage();
        List<CustomPageData> customPageDataList = new ArrayList<>();
        if (customPage.getId() == null) {
            // 新建
            customPage.setCreatedAt(new Date());
            customPage.setUpdatedAt(new Date());
            customPage.setType(req.getCustomPage().getType() == null ? CustomPageTypeEnum.ADMIN.getType() : req.getCustomPage().getType());
            customPage.setTenantId(0L);
            customPageMapper.insert(customPage);
        } else {
            // 修改
            customPage.setUpdatedAt(new Date());
            customPageMapper.updateByPrimaryKeySelective(customPage);

            customPageDataMapper.deleteByCustomPageId(customPage.getId());
        }

        req.getCustomPageDataList().stream().forEach(item -> {
            item.setCustomPageId(customPage.getId());
            item.setCreatedAt(new Date());
            customPageDataList.add(item);
        });
        customPageDataMapper.batchInsert(customPageDataList);

        redisTemplate.delete("HomeCustomResp");
        return new BaseResp();
    }

    @Override
    public ResultData<CustomPageEditVO> getCustomPageDetail(Long id) {
        CustomPageEditVO vo = new CustomPageEditVO();

        vo.setCustomPage(customPageMapper.selectByPrimaryKey(id));
        List<CustomPageData> customPageDataList = customPageDataMapper.findAllByCustomPageId(id);

        // 获取所有的商品,优惠券信息
        List<Long> spuIds = new ArrayList<>();
        List<Long> couponIds = new ArrayList<>();
        customPageDataList.stream().forEach(item -> {
            if (CustomPageDataTypeEnum.PRODUCT.getType().equals(item.getType()) || CustomPageDataTypeEnum.TO_CART.getType().equals(item.getType())) {
                spuIds.add(item.getRelateId());
            }
            if (CustomPageDataTypeEnum.COUPON.getType().equals(item.getType()) || CustomPageDataTypeEnum.GET_COUPON.getType().equals(item.getType())) {
                couponIds.add(item.getRelateId());
            }
        });

        Map<Long, Spu> spuMap = CollectionUtils.isEmpty(spuIds) ? new HashMap<>() : daoService.getSpuMap(spuIds);
        Map<Long, Coupon> couponMap = CollectionUtils.isEmpty(couponIds) ? new HashMap<>() : daoService.getCouponMap(couponIds);

        List<CustomPageDataVO> customPageDataVOList = new ArrayList<>();
        customPageDataList.stream().forEach(item -> {
            CustomPageDataVO customPageDataVO = new CustomPageDataVO();
            BeanUtils.copyProperties(item, customPageDataVO);
            if (CustomPageDataTypeEnum.PRODUCT.getType().equals(item.getType()) || CustomPageDataTypeEnum.TO_CART.getType().equals(item.getType())) {
                customPageDataVO.setSpu(spuMap.get(item.getRelateId()));
            }
            if (CustomPageDataTypeEnum.COUPON.getType().equals(item.getType()) || CustomPageDataTypeEnum.GET_COUPON.getType().equals(item.getType())) {
                customPageDataVO.setCoupon(couponMap.get(item.getRelateId()));
            }
            customPageDataVOList.add(customPageDataVO);
        });

        vo.setCustomPageDataList(customPageDataVOList);

        return new ResultData<>(vo);
    }

    @Override
    public BaseResp deleteCustomPage(Long id) {
        customPageMapper.deleteByPrimaryKey(id);
        customPageDataMapper.deleteByCustomPageId(id);
        return new BaseResp();
    }

    @Override
    public ResultData<BasePageResp<CustomPage>> getCustomPage(PageReq req) {
        Page page = PageHelper.startPage(req.getPageNo(), req.getPageSize());
        List<Byte> types = new ArrayList<>();
        types.add(CustomPageTypeEnum.ADMIN.getType());
        types.add(CustomPageTypeEnum.TEMPLATE.getType());
        req.setTypes(types);
        List<CustomPage> list = customPageMapper.findAllPage(req);
        return PageHelpUtil.buildPage(list, page);
    }

    @Override
    public BaseResp editPoster(Poster poster) {
        if (poster.getId() == null) {
            // 添加
            poster.setCreatedAt(new Date());
            poster.setUpdatedAt(new Date());
            posterMapper.insert(poster);
        } else {
            // 编辑
            poster.setUpdatedAt(new Date());
            posterMapper.updateByPrimaryKeySelective(poster);
        }
        return new BaseResp();
    }

    @Override
    public ResultData<BasePageResp<Poster>> getPosterPage(PageReq req) {
        Page page = PageHelper.startPage(req.getPageNo(), req.getPageSize());
        List<Poster> list = posterMapper.findAllPage(req);
        return PageHelpUtil.buildPage(list, page);
    }


    @Override
    public ResultData<Poster> getPosterDetail(Long id) {
        return new ResultData<>(posterMapper.selectByPrimaryKey(id));
    }

    @Override
    public BaseResp deletePoster(Long id) {
        posterMapper.deleteByPrimaryKey(id);
        return new BaseResp();
    }


    @Override
    public BaseResp editOnePost(OnePost onePost) {
        if (onePost.getId() == null) {
            // 添加
            onePost.setCreatedAt(new Date());
            onePost.setUpdatedAt(new Date());
            onePostMapper.insert(onePost);
        } else {
            // 编辑
            onePost.setUpdatedAt(new Date());
            onePostMapper.updateByPrimaryKeySelective(onePost);
        }
        return new BaseResp();
    }

    @Override
    public ResultData<BasePageResp<OnePost>> getOnePostPage(PageReq req) {
        Page page = PageHelper.startPage(req.getPageNo(), req.getPageSize());
        List<OnePost> list = onePostMapper.findAllPage(req);
        return PageHelpUtil.buildPage(list, page);
    }


    @Override
    public ResultData<OnePostVO> getOnePostDetail(Long id) {
        OnePostVO vo = new OnePostVO();
        OnePost onePost = onePostMapper.selectByPrimaryKey(id);
        BeanUtils.copyProperties(onePost, vo);

        if (OnePostTypeEnum.PRODUCT.getType().equals(onePost.getType())) {
            vo.setSpu(spuMapper.selectByPrimaryKey(onePost.getSpuId()));
        }

        return new ResultData<>(vo);
    }

    @Override
    public BaseResp deleteOnePost(Long id) {
        onePostMapper.deleteByPrimaryKey(id);
        return new BaseResp();
    }
}